/*
*
定义包名。package main 表示一个可独立执行的程序，每个 Go 应用程序都需要包含一个名为 main 的包，并且该包下包含一个叫main()的函数（该函数是Go可执行程序的执行起点，既不能带参数，也不能定义返回值）。
小结：只有package名称为main的包可以包含main()函数，而且一个可执行程序有且仅有一个main包。和 java 中 main 是一个意思。
*/
package main

/**
import 语句用于导入该程序所依赖的包。由于本示例程序用到了 Println() 函数，所以需要导入该函数所属的 fmt 包。fmt 包实现了格式化 IO（输入/输出)
注意：在go中，不使用的包需要及时清除，否则编译时报错
*/
import "fmt"

/*
*
main() 函数是程序入口。 Go 中所有函数以关键字 func 开头，每一个可执行程序（注意，是可执行程序，而不是源文件）都必须包含 main() 函数。通常来说，main() 是程序启动后第一个执行的函数。
但是也有例外，如果有 init() 函数，则会先执行init()函数。init函数用于 package 的初始化，该函数是 go 语言的一个重要特性。

可执行程序运行方式：可以使用在 IDE 中点击 main() 函数左侧绿色按钮运行程序，也可以在控制台中执行：go run HelloGo1.go 来运行程序。但并不推荐在正式的大项目中使用 go run 子命令。
go run 子命令只是一种方便的方式来运行简单的Go程序。对于正式的项目，最好使用 go build 或者 go install 子命令来编译生成可执行程序文件，运行可执行程序文件
*/
var i = globalVar()

func main() {

	// TIPS：在 Go 程序中，换行代表一个语句结束。Go 语言中不需要像 Java 一样以分号结尾，因为这些工作都将由 Go 编译器自动完成。
	// 如果打算将多个语句写在同一行，那么它们则必须使用分号“;”人为区分。但在实际开发中并不鼓励这种做法
	fmt.Println("hello golang1!")
	fmt.Printf("hello golang2! \n")
	fmt.Print("hello golang3!")
	/*
		Go语言中，使用 大小写 来决定 标识符（常量、变量、类型、接口、结构或函数）是否可以被【外部包】所调用。
		如果标识符以大写字母开头，那么其对象就可以被【外部包】的代码所使用（使用时程序需要先导入这个包），如同面向对象语言中的 public。例如上面使用到的 Print 函数，都是大写字母开头。
		如果标识符以小写字母开头，则对包外是不可见的，但是它们在【整个包的内部】是可见并且可用的，如同面向对象语言中的 private
	*/
}

/*
		init()说明（此函数在编码过程中不是必须实现的）：
		1 init 函数是用于程序执行前做包的初始化的函数，比如初始化包里的变量等；
	    2 每个包可以拥有多个 init 函数；
	    3 包的每个源文件也可以拥有多个 init 函数；
	    4 同一个包中多个 init 函数的执行顺序 go 语言没有明确的定义（说明）；
	    5 不同包的 init 函数按照包导入的依赖关系决定该初始化函数的执行顺序；
	    6 init 函数不能被其他函数调用，而是在 main 函数执行之前，自动被调用。但是 init 函数并不是最先被执行的，如果声明了 const 或全局变量，那么 init 函数会在它们之后执行，例如本例中的全局变量 i
		7 对同一个 go 文件的 init() 调用顺序是从上到下的；
		8 对同一个 package 中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的 init() 函数；
		9 对于不同的 package，如果不相互依赖的话，按照 main 包中"先import的后调用"的顺序调用其包中的 init()，如果 package 存在依赖，
		  则先调用最早被依赖的 package 中的 init()，最后调用 main 函数。示例可见：https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cb5fcbeb6a284b2b94400a83e6803659~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp
	      还有一种情况，例入引入 mysql，如果是使用 import _ "github.com/go-sql-driver/mysql" 这种方式引入的，也是会先调用 mysql 包中的 init 函数。
*/
func init() {

	fmt.Println("我是init()，比main()函数还先执行1")
}

func init() {

	fmt.Println("我是init()，比main()函数还先执行2")
}

func globalVar() int {
	fmt.Println("这是全局变量初始化时的执行")
	return 1
}
